home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / forms / FORMS / menu.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  7KB  |  264 lines

  1. /*
  2.  * menu.c
  3.  *
  4.  * Forms Object class: MENU
  5.  *
  6.  * Written by: Mark Overmars and Trevor Paquette
  7.  *
  8.  * Version 2.2 a
  9.  * Date: Jun 28, 1993
  10.  */
  11.  
  12. #include <malloc.h>
  13. #include <strings.h>
  14. #include "gl/device.h"
  15. #include "gl/gl.h"
  16. #include "forms.h"
  17.  
  18. /* Object specific information */
  19. typedef struct{
  20.    long  val;                /* last menu item selected */
  21.    int  numitems;            /* number of items in menu */
  22.    char *items[FL_MENU_MAXITEMS+1];    /* individual menu items */
  23.    long mode[FL_MENU_MAXITEMS+1];    /* menu item mode */
  24.    char *shortcut[FL_MENU_MAXITEMS+1];    /* the shortcuts for the items */
  25.    int showsymbol;            /* whether menu symbol should be shown */
  26. } SPEC;
  27.  
  28. static int do_menu(FL_OBJECT *ob)
  29. /* Creates the menu and shows it. Returns the item selected. */
  30. {
  31.   int i;            /* Counter */
  32.   long menu;            /* The menu */
  33.   int val;
  34.   SPEC *sp = ((SPEC *)(ob->spec));
  35.   menu = newpup();
  36.   for (i=1; i<=sp->numitems;i++) addtopup(menu,sp->items[i]);
  37.   for (i=1; i<=sp->numitems;i++) setpup(menu, i, sp->mode[i]);
  38.   val = (int) dopup(menu);
  39.   freepup(menu);
  40.   return val;
  41. }
  42.  
  43. static int handle_menu(FL_OBJECT *ob,int event,float mx,float my,char key)
  44. /* Handles an event, returns whether value has changed. */
  45. {
  46.   SPEC *sp = ((SPEC *)(ob->spec));
  47.   int i, col;
  48.   char shortcut[4];
  49.   switch (event)
  50.   {
  51.     case FL_DRAW:
  52.         /* Draw the object */
  53.       if ((ob->type == FL_PUSH_MENU && ob->pushed) ||
  54.           (ob->type == FL_TOUCH_MENU && ob->belowmouse))
  55.           col = ob->col2;
  56.         else
  57.       col = ob->col1;
  58.     fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,col,FL_MENU_BW);
  59.     fl_drw_text(ob->align,ob->x,ob->y,ob->w,ob->h,
  60.             ob->lcol,ob->lsize,ob->lstyle,ob->label);
  61.     if (sp->showsymbol)
  62.       fl_drw_text(0,ob->x+ob->w-0.8*ob->h,ob->y+0.2*ob->h,
  63.             0.6*ob->h,0.6*ob->h,col,0.0,0,"@menu");
  64.         return 0;
  65.     case FL_ENTER:
  66.     if (ob->type == FL_TOUCH_MENU)
  67.     {
  68.           fl_redraw_object(ob);
  69.       sp->val = do_menu(ob);
  70.     }
  71.     return 0;
  72.     case FL_LEAVE:
  73.         fl_redraw_object(ob);
  74.     return (ob->type == FL_TOUCH_MENU && sp->val != -1);
  75.     case FL_PUSH:
  76.     if (ob->type == FL_PUSH_MENU)
  77.     {
  78.           fl_redraw_object(ob);
  79.       sp->val = do_menu(ob);
  80.           qenter(MOUSE1,0);        /* dopup eats up this event */
  81.     }
  82.     return 0;
  83.     case FL_RELEASE:
  84.         fl_redraw_object(ob);
  85.     return (ob->type == FL_PUSH_MENU && sp->val != -1);
  86.     case FL_SHORTCUT:
  87.     i = 0;
  88.     if (key >=128) 
  89.       {shortcut[i++] = '#'; key -= 128;}
  90.     if (key <=26) 
  91.       {shortcut[i++] = '^'; shortcut[i++] = key+'a'-1;}
  92.     else
  93.       shortcut[i++] = key;
  94.     shortcut[i] = '\0';
  95.     for (i=1; i<= sp->numitems; i++)
  96.       if (strstr(sp->shortcut[i],shortcut) != NULL && !(sp->mode[i] & PUP_GREY)) 
  97.         { sp->val = i; return 1;}
  98.     return 0;    
  99.     case FL_FREEMEM:
  100.     for (i=1; i <= sp->numitems;i++) 
  101.       { free(sp->items[i]); free(sp->shortcut[i]); }
  102.     free(ob->spec);
  103.     return 0;
  104.     default:
  105.         return 0;
  106.   }
  107. }
  108.  
  109. /*-------------------------------------------*/
  110.  
  111. FL_OBJECT *fl_create_menu(int type,float x,float y,float w,float h,char label[])
  112. /* creates an object */
  113. {
  114.   FL_OBJECT *ob;
  115.   SPEC *sp;
  116.   ob = fl_make_object(FL_MENU,type,x,y,w,h,label,handle_menu);
  117.   ob->boxtype = FL_MENU_BOXTYPE;
  118.   ob->col1 = FL_MENU_COL1;
  119.   ob->col2 = FL_MENU_COL2;
  120.   ob->lcol = FL_MENU_LCOL;
  121.   ob->align = FL_MENU_ALIGN;
  122.   
  123.   ob->spec = (int *) fl_malloc(sizeof(SPEC));
  124.   sp = ((SPEC *)(ob->spec));
  125.   sp->val = 0;
  126.   sp->numitems = 0;
  127.   sp->showsymbol = 0;
  128.   return ob;
  129. }
  130.  
  131. FL_OBJECT *fl_add_menu(int type, float x, float y, float w, float h, char label[])
  132. /* Adds an object */
  133. {
  134.   FL_OBJECT *ob;
  135.   ob = fl_create_menu(type,x,y,w,h,label);
  136.   fl_add_object(fl_current_form,ob);
  137.   return ob;
  138. }
  139.  
  140. /*-------------------------------------*/
  141.  
  142. void fl_clear_menu(FL_OBJECT *ob)
  143. /* Clears the menu object */
  144. {
  145.   int i;
  146.   SPEC *sp = ((SPEC *)(ob->spec));
  147.   sp->val = 0;
  148.   for (i=1; i <= sp->numitems; i++)
  149.     { free(sp->items[i]); free(sp->shortcut[i]); sp->mode[i] = PUP_NONE; }
  150.   sp->numitems = 0;
  151. }
  152.  
  153. static void addto_menu(FL_OBJECT *ob, char str[])
  154. /* Adds a line to the menu item. */
  155. {
  156.   SPEC *sp = ((SPEC *)(ob->spec));
  157.   if (sp->numitems >= FL_MENU_MAXITEMS) return;
  158.   sp->numitems++;
  159.   sp->items[sp->numitems] = (char *) fl_malloc(FL_MENU_MAXSTR+1);
  160.   strncpy(sp->items[sp->numitems],str,FL_MENU_MAXSTR);
  161.   sp->items[sp->numitems][FL_MENU_MAXSTR] = '\0';
  162.   sp->shortcut[sp->numitems] = (char *) fl_malloc(1);
  163.   sp->shortcut[sp->numitems][0] = '\0';
  164.   sp->mode[sp->numitems] = PUP_NONE;
  165. }
  166.  
  167.  
  168. void fl_set_menu(FL_OBJECT *ob, char menustr[])
  169. /* Sets the menu to a particular menu string */
  170. {
  171.   fl_clear_menu(ob);
  172.   fl_addto_menu(ob, menustr);
  173. }
  174.  
  175. void fl_addto_menu(FL_OBJECT *ob, char menustr[])
  176. /* Adds a line to the menu item. */
  177. {
  178.   char ttt[256];
  179.   int i = 0, j = 0;
  180.   while (menustr[i] != '\0')
  181.   {
  182.     if (menustr[i] == '|')
  183.       { ttt[j] = '\0'; addto_menu(ob, ttt); j = 0; }
  184.     else
  185.       ttt[j++] = menustr[i];
  186.     i++;
  187.   }
  188.   if (j != 0) { ttt[j] = '\0'; addto_menu(ob, ttt);}
  189. }
  190.  
  191. void fl_replace_menu_item(FL_OBJECT *ob, int numb, char str[])
  192. /* Replaces a line in the menu item. */
  193. {
  194.   SPEC *sp = ((SPEC *)(ob->spec));
  195.   if (numb<1 || numb > sp->numitems) return;
  196.   strncpy(sp->items[numb],str,FL_MENU_MAXSTR);
  197.   sp->items[numb][FL_MENU_MAXSTR] = '\0';
  198. }
  199.  
  200. void fl_delete_menu_item(FL_OBJECT *ob, int numb)
  201. /* Removes a line from the menu item. */
  202. {
  203.   int i;
  204.   SPEC *sp = ((SPEC *)(ob->spec));
  205.   if (numb<1 || numb >sp->numitems) return;
  206.   free(sp->items[numb]);
  207.   free(sp->shortcut[numb]);
  208.   for (i=numb; i<sp->numitems;i++)
  209.   {
  210.     sp->items[i] = sp->items[i+1];
  211.     sp->mode[i] = sp->mode[i+1];
  212.     sp->shortcut[i] = sp->shortcut[i+1];
  213.   }
  214.   sp->mode[sp->numitems] = PUP_NONE;
  215.   sp->numitems--;
  216. }  
  217.  
  218. /*------------------------------------------*/
  219.  
  220. void fl_set_menu_item_shortcut(FL_OBJECT *ob, int numb, char str[])
  221. {
  222.   SPEC *sp = ((SPEC *)(ob->spec));
  223.   char sss[1024];
  224.   int i;
  225.   sp->shortcut[numb] = (char *) realloc(sp->shortcut[numb],strlen(str)+1);
  226.   strcpy(sp->shortcut[numb], str);
  227.   sss[0] = '\0';
  228.   for (i=1; i <= sp->numitems; i++) strcat(sss, sp->shortcut[i]);
  229.   fl_set_object_shortcut(ob, sss);
  230. }
  231.  
  232. void fl_set_menu_item_mode(FL_OBJECT *ob, int numb, long mode)
  233. /* Sets the display mode for the menu item */
  234. {
  235.   SPEC *sp = ((SPEC *)(ob->spec));
  236.   sp->mode[numb] = mode;
  237. }
  238.  
  239. void fl_show_menu_symbol(FL_OBJECT *ob, int show)
  240. /* Makes the menu symbol visible or not */
  241. {
  242.   SPEC *sp = ((SPEC *)(ob->spec));
  243.   sp->showsymbol = show;
  244.   fl_redraw_object(ob);
  245. }
  246.  
  247. /*------------------------------------------*/
  248.  
  249. int fl_get_menu(FL_OBJECT *ob)
  250. /* Returns the number of the menu item selected. */
  251. {
  252.   SPEC *sp = ((SPEC *)(ob->spec));
  253.   return sp->val;
  254. }
  255.  
  256. char *fl_get_menu_text(FL_OBJECT *ob)
  257. /* Returns the text of the menu item selected. */
  258. {
  259.   SPEC *sp = ((SPEC *)(ob->spec));
  260.   if (sp->val <= 0 || sp->val > sp->numitems) return NULL;
  261.   return sp->items[sp->val];
  262. }
  263.  
  264.